﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using libC.semantic;

namespace libC.translate
{
    /// <summary>
    /// wrap code 生成接口
    /// </summary>
    internal interface IWrapGenerator
    {
        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="semAnaly"></param>
        void parse(semanticAnalyzer semAnaly);

        /// <summary>
        /// 获取 wrap code
        /// </summary>
        /// <returns></returns>
        string getWrapCode();
    }

    /// <summary>
    /// wrap 语言
    /// </summary>
    public enum wrapLang
    {
        /// <summary>
        /// C 语言
        /// </summary>
        C,
        /// <summary>
        /// C# 语言
        /// </summary>
        C_SHARP
    }

    /// <summary>
    /// wrap 代码生成器
    /// </summary>
    public class wrapCodeGenerator
    {
        /// <summary>
        /// 生成code
        /// </summary>
        /// <param name="semAnaly">语义分析器</param>
        /// <param name="lang">语言枚举</param>
        /// <param name="dllFile">dll 文件</param>
        /// <param name="warpName">wrap文件和类名</param>
        /// <param name="nameSpace">命名空间名（c#可用）</param>
        /// <param name="forceSafe">强制安全模式</param>
        /// <returns></returns>
        public static string codeGen(semanticAnalyzer semAnaly, wrapLang lang , string dllFile , string warpName = "" , string nameSpace = "" , bool forceSafe = true)
        {
            string result = null;
            IWrapGenerator generator = null;
            if (string.IsNullOrEmpty(warpName)) warpName = "Wrap";
            //找分析器
            switch (lang)
            {
                case wrapLang.C:
                    var c_g = new generatorC();
                    c_g.dllFile = dllFile;
                    c_g.className = warpName;
                    c_g.nameSpace = nameSpace;
                    generator = c_g;
                    break;
                case wrapLang.C_SHARP:
                    var cs_g = new generatorCSharp();
                    cs_g.dllFile = dllFile; 
                    cs_g.className = warpName;
                    cs_g.nameSpace = nameSpace;
                    cs_g.forceSafe = forceSafe;
                    generator = cs_g;
                    break;
            }

            //gen code 
            generator.parse(semAnaly);
            result = generator.getWrapCode();
            return result;
        }
    }
}
